package cn.ysnk.clz.config;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;

import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.core.Controller;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.render.ViewType;

import cn.ysnk.clz.config.annotation.ControllerAnnotation;
import cn.ysnk.clz.config.annotation.EntityAnnotation;
import cn.ysnk.clz.interceptor.security.MySecurityMetadataSource;
import cn.ysnk.clz.interceptor.security.role.RoleEnum;

public class BaseConfig extends JFinalConfig {

	public static final boolean isDebug = true;
	@Override
	public void configConstant(Constants constans) {
		loadPropertyFile("a_little_config.txt");
		constans.setDevMode(true);
		constans.setViewType(ViewType.JSP);
		constans.setBaseUploadPath("upload");
		constans.setBaseDownloadPath("download");
		constans.setError403View("/admin/common/403.jsp");
		constans.setError404View("/admin/common/404.jsp");
		constans.setError500View("/admin/common/500.jsp");
	}
	@Override
	public void configRoute(Routes routes) {
		String controllerScannerPath = PathKit.getRootClassPath() + File.separator + getProperty("controllerScannerPath").replace(".", File.separator);
		if(isDebug)
			System.out.println("========读取路由配置开始========\n开始扫描包“"+getProperty("controllerScannerPath")+"”下Controller...");
		loadControllerClass(getProperty("controllerScannerPath"), controllerScannerPath, routes);
		if(isDebug)
			System.out.println("========读取路由配置结束========");
	}

	@Override
	public void configHandler(Handlers arg0) {
	}

	@Override
	public void configInterceptor(Interceptors arg0) {

	}

	@Override
	public void configPlugin(Plugins me) {
		DruidPlugin cp = new DruidPlugin(getProperty("jdbcUrl"),
				getProperty("user"), getProperty("password"));
		me.add(cp);
		ActiveRecordPlugin arp = new ActiveRecordPlugin(cp);
		me.add(arp);
		String entityScannerPath = PathKit.getRootClassPath() + File.separator + getProperty("entityScannerPath").replace(".", File.separator);
		if(isDebug)
			System.out.println("========读取mapping配置开始========\n开始扫描包“"+getProperty("entityScannerPath")+"”下Controller...");
		loadEntityClass(getProperty("entityScannerPath"),entityScannerPath,arp);
		if(isDebug)
			System.out.println("========读取mapping配置结束========");
	}
	
	private void loadEntityClass(String packageName,String dir,ActiveRecordPlugin arp){
		File entityDir = new File(dir);
		File[] subFiles = entityDir.listFiles();
		for(File f:subFiles){
			if(f.isDirectory()&&!f.isHidden()&&!f.getName().startsWith(".")){
				loadEntityClass(packageName+"."+f.getName(),f.getAbsolutePath(),arp);
			}else if(f.isFile()&&!f.isHidden()&&!f.getName().startsWith(".")){
				try {
					Class c = Class.forName(packageName+"."+f.getName().substring(0,f.getName().lastIndexOf(".")));
					if(c.isAnnotationPresent(EntityAnnotation.class)){
						EntityAnnotation annotation = (EntityAnnotation) c.getDeclaredAnnotation(EntityAnnotation.class);
						String tabelName = annotation.tableName();
						if(isDebug)
							System.out.println("扫描到entity---"+c.getName()+",表名配置为----"+tabelName);
						arp.addMapping(tabelName, (Class<? extends Model<?>>)c);
					}
					
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void loadControllerClass(String packageName,String dir,Routes routes){
		File entityDir = new File(dir);
		File[] subFiles = entityDir.listFiles();
		for(File f:subFiles){
			if(f.isDirectory()&&!f.isHidden()&&!f.getName().startsWith(".")){
				loadControllerClass(packageName+"."+f.getName(),f.getAbsolutePath(),routes);
			}else if(f.isFile()&&!f.isHidden()&&!f.getName().startsWith(".")){
				try {
					Class c = Class.forName(packageName+"."+f.getName().substring(0,f.getName().lastIndexOf(".")));
					if(c.isAnnotationPresent(ControllerAnnotation.class)){
						ControllerAnnotation annotation = (ControllerAnnotation) c.getDeclaredAnnotation(ControllerAnnotation.class);
						String url = annotation.url();
						RoleEnum[] roleTypes = annotation.roleType();
						if(isDebug)
							System.out.println("扫描到controller---"+c.getName()+",url配置为----"+url+",角色定义为："+roleTypes);
						//配置角色与url对应
						if(roleTypes.length>0){
							Collection<ConfigAttribute> atts = new ArrayList<ConfigAttribute>();
							for(RoleEnum r:roleTypes){
								ConfigAttribute att = new SecurityConfig(r.name());
								atts.add(att);
							}
							MySecurityMetadataSource.resourceMap.put(url, atts);
						}
						routes.add(url, (Class<? extends Controller>)c);
					}
					
				} catch (ClassNotFoundException e) {
					e.printStackTrace();
				}
			}
		}
	}

}
